package com.dtflys.easyel.runtime.eval;

import com.dtflys.easyel.antlr.EasyElParser;
import com.dtflys.easyel.ast.ASTBinaryExpression;
import com.dtflys.easyel.exception.EasyElEvalException;
import com.dtflys.easyel.runtime.EasyElRuntimeContext;
import com.dtflys.easyel.runtime.wrapper.BooleanWrapper;
import com.dtflys.easyel.utils.MetaHelper;
import org.antlr.v4.runtime.Token;

/**
 * 布尔求值器
 * @author gongjun[jun.gong@thebeastshop.com]
 * @since v1.0.0
 */
public class BooleanEvaluator {

    public Boolean evaluate(EasyElRuntimeContext context, ASTBinaryExpression node, Object left, Object right) {
        left = MetaHelper.wrap(left);
        right = MetaHelper.wrap(right);

        Class leftClass = left.getClass();
        Class rightClass = right.getClass();
        Token op = node.getOperation();
        if (!(left instanceof BooleanWrapper)) {
            throw new EasyElEvalException(context, node,
                    "operator \"" + op.getText() + "\" do not support for type " + leftClass);
        }
        if (!(right instanceof BooleanWrapper)) {
            throw new EasyElEvalException(context, node,
                    "operator \"" + op.getText() + "\" do not support for type " + rightClass);
        }
        switch (op.getType()) {
            case EasyElParser.J_AND:
            case EasyElParser.AND:
                return ((BooleanWrapper) left).and((BooleanWrapper) right);
            case EasyElParser.J_OR:
            case EasyElParser.OR:
                return ((BooleanWrapper) left).or((BooleanWrapper) right);
        }
        throw new EasyElEvalException(context, node,
                "operator \"" + op.getText() + "\" do not support for type " + leftClass + " and " + rightClass);
    }

}
